namespace LinkedTU.Data.Migrations
{
    using System;
    using System.Collections.Generic;
    using System.Data.Entity;
    using System.Data.Entity.Migrations;
    using System.Linq;
    using LinkedTU.Models;
    using LinkedTU.Data.Extensions;
    using LinkedTU.Common.Interfaces;
    using LinkedTU.Data.Providers;
    using Microsoft.AspNet.Identity.EntityFramework;
    using LinkedTU.Common.Constants;
    using System.Configuration;
    using Microsoft.AspNet.Identity;

    public sealed class DbContextMigrationConfiguration : DbMigrationsConfiguration<LinkedTuDbContext>
    {
        public DbContextMigrationConfiguration()
        {
            AutomaticMigrationsEnabled = true;
            AutomaticMigrationDataLossAllowed = true;
            ContextKey = "LinkedTU.Data.LinkedTuDbContext";
        }

        protected override void Seed(LinkedTuDbContext context)
        {
            this.SeedRoles(context);
            this.SeedUsers(context);
            this.SeedCountries(context);
            this.SeedCities(context);
            this.SeedCompanySizes(context);
            this.SeedLanguages(context);
        }

        private void SeedRoles(LinkedTuDbContext context)
        {
            if (!context.Roles.Any())
            {
                var store = new RoleStore<IdentityRole>(context);
                var manager = new RoleManager<IdentityRole>(store);

                manager.Create(new IdentityRole() { Name = Roles.Administrator });
                manager.Create(new IdentityRole() { Name = Roles.Company });
                manager.Create(new IdentityRole() { Name = Roles.Professor });
                manager.Create(new IdentityRole() { Name = Roles.Student });

                context.SaveChanges();
            }
        }

        private void SeedUsers(LinkedTuDbContext context)
        {
            if (!context.Users.Any())
            {
                var store = new UserStore<ApplicationUser>(context);
                var manager = new UserManager<ApplicationUser>(store);
                var user = new ApplicationUser
                {
                    Email = ConfigurationManager.AppSettings.Get("RootEmail"),
                    UserName = ConfigurationManager.AppSettings.Get("RootUser"),
                };

                manager.Create(user, ConfigurationManager.AppSettings.Get("RootPass"));
                manager.AddToRole(user.Id, Roles.Administrator);

                context.SaveChanges();
            }
        }

        private void SeedCountries(LinkedTuDbContext context)
        {
            if (!context.Countries.Any())
            {
                IClassificatorProvider<Country> countriesProvider = new CountryProvider();

                var countries = countriesProvider.GetClassificators()
                    .OrderBy(c => c.DisplayName);

                int i = 0;

                foreach (var country in countries)
                {
                    country.Order = ++i;
                    context.Countries.AddOrUpdate(x => x.CountryCode, country);
                }

                context.SaveChanges();
            }
        }

        private void SeedCities(LinkedTuDbContext context)
        {
            if (!context.Cities.Any())
            {
                IClassificatorProvider<City> citiesProvider = new CityProvider();

                var cities = citiesProvider.GetClassificators()
                    .OrderBy(c => c.DisplayName);

                int i = 0;

                foreach (var city in cities)
                {
                    var country = context.Countries.FirstOrDefault(c => c.DisplayName == city.Country.DisplayName);

                    if (country != null)
                    {
                        city.Order = ++i;
                        city.Country = country;
                        context.Cities.AddOrUpdate(c => c.DisplayName, city);
                    }
                }

                context.SaveChanges();
            }
        }

        private void SeedCompanySizes(LinkedTuDbContext context)
        {
            if (!context.CompanySizes.Any())
            {
                IClassificatorProvider<CompanySize> companySizesProvider = new CompanySizeProvider();

                var companySizes = companySizesProvider.GetClassificators()
                    .OrderBy(cs => cs.MinTeamMembers)
                    .ThenBy(cs => cs.MaxTeamMembers);

                int i = 0;

                foreach (var size in companySizes)
                {
                    size.Order = ++i;
                    context.CompanySizes.Add(size);
                }

                context.SaveChanges();
            }
        }

        private void SeedLanguages(LinkedTuDbContext context)
        {
            if (!context.Languages.Any())
            {
                IClassificatorProvider<Language> langProvider = new LanguageProvider();

                var languages = langProvider.GetClassificators()
                    .OrderBy(l => l.DisplayName);

                var i = 0;

                foreach (var language in languages)
                {
                    language.Order = ++i;
                    context.Languages.Add(language);
                }

                context.SaveChanges();
            }
        }
    }
}
